/****************************************************************************
*					PGMStruct
*
*	Description:	A class for representing Probabilistic Graphical Model (PGM)
*
****************************************************************************/

#include <vector>
#include "DataSet.h"
#include "Feature.h"
#include "DomainFeatures.h"

#ifndef _PGMStruct_H
#define _PGMStruct_H

class PGMStruct {
  private:

  protected:

  public:

	/* Data */
	  // number of variables
	unsigned int nVars;
	  // Variables:
	std::vector <unsigned int> variables;
	  // vector of number of values of variables
	std::vector <unsigned int> numOfValues;
	  // vector of different used features
	std::vector <Feature*> featureTypes;
	  // vector of weights (parameters of PGM)
	std::vector <float> weights;
	  // features of PGM that are defined for certain values of certain variables and use a specific featureType with a specific weight
	std::vector <DomainFeatures> features;
 

	/* Functions */
	  // Standard constructor - empty one
	PGMStruct();
      
	  // Standard destructor - empty one
    ~PGMStruct();

	  // Adds a feature with specified varIDs (domain)
	int addFeature (std::vector <unsigned int>& domain, Feature* newFeature);

	  // Adds a feature with specified varIDs (domain)
	int addFeature (std::vector <unsigned int>& domain, Feature* newFeature, const float& newWeight);

	  // Removes all elements in internal variables
	void clear (void);

	  // Initialize internal variables by observing data set parameters
	int initStructure (DataSet& dataSet);

	  // Calculates value of weighted sum of features in a specified domain in a given set of values
	inline float calculate (const unsigned int& domainFeatNum, std::vector<unsigned int>& vals) const {
		float toRet = 0.0;
		for (unsigned int i = 0; i < features[domainFeatNum].featsIDs.size(); i++)
			if (features[domainFeatNum].weightsIDs[i] >= 0)
				toRet += weights[features[domainFeatNum].weightsIDs[i]] * featureTypes[features[domainFeatNum].featsIDs[i]]->calculate(vals);
		return toRet; }
	
}; // end of class

#endif // _PGMStruct_H
